package unq.uis.robots.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Vector;
import org.uqbar.commons.model.UserException;
import org.uqbar.commons.utils.Observable;

@Observable
public class Sistema implements Serializable{
	
	
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 25809790310338561L;
	private static Sistema instance = new Sistema(); 
	private List<Jugador> jugadores;
	private List<Robot> robotsSistema = new ArrayList<Robot>();
	private List<MejoraDeRobot> mejorasDisponibles;
	
	private Sistema(){
		this.jugadores = new Vector<Jugador>();		
		this.mejorasDisponibles = new Vector<MejoraDeRobot>();
		this.agregarMejoras();
		this.agregarRobots();
	}
	
	private void agregarRobots() {
		Robot robot1 = new Robot("jony", 45, 10);
		Robot robot2 = new Robot("luigi", 60, 30);
		Robot robot3 = new Robot("octavio", 45, 10);
		Robot robot4 = new Robot("wall-e", 45, 10);
		Robot robot5 = new Robot("goku", 45, 10);
		Robot robot6 = new Robot("sonic", 45, 10);
		this.agregarRobot(robot1);
		this.agregarRobot(robot2);
		this.agregarRobot(robot3);
		this.agregarRobot(robot4);
		this.agregarRobot(robot5);
		this.agregarRobot(robot6);
	}

	private void agregarMejoras() {
		this.mejorasDisponibles.add(new MejoraDeRobot("Aprendizaje de Técnicas de Jiu-jitsu", 21, 250));
		this.mejorasDisponibles.add(new MejoraDeRobot("Mochila voladora de propulsión", 4, 96));
		this.mejorasDisponibles.add(new MejoraDeRobot("Lanza-cohetes teledirigidos", 13, 156));		
	}

	public static Sistema getInstance(){
		return instance;
	}	
	
	public void aceptarOferta(int oferta, int precioBase, Jugador comprador, Robot robotSeleccionado){
		
		if (oferta > comprador.getDinero()){
			throw new UserException("No puede ofertar más dinero del que tiene disponible!");
		}
		
		if ( Math.random() <= 0.9 * Math.pow((oferta / precioBase), 2) ){
			
			this.venderRobot(comprador, robotSeleccionado, oferta);
		}
		else{
			comprador.disminuirDinero((int) (oferta * 0.02));
			throw new UserException("Su oferta no fue aceptada por el Sistema, usted pierde el 2% del dinero ofertado. Intentelo nuevamente");
		}
	}
	
	public void venderRobot(Jugador comprador, Robot robotSeleccionado, int oferta){
		if(this.esUnRobotDelSistema(robotSeleccionado)){
		robotSeleccionado.setDuenio(comprador);
		int indice = this.getRobotsSistema().indexOf(robotSeleccionado);
		Robot robotComprado = this.getRobotsSistema().get(indice);
		this.getRobotsSistema().remove(robotSeleccionado);
		comprador.addRobot(robotComprado);
		comprador.disminuirDinero(oferta);
		}
	}
	
	private boolean esUnRobotDelSistema(Robot robotSeleccionado) {
		return this.getRobotsSistema().contains(robotSeleccionado);
	}

	public List<Robot> getRobots(Jugador jugador) {
		List<Robot> resultado = new Vector<Robot>();
		for(Jugador j : this.jugadores){
			if(!j.equals(jugador))
				resultado.addAll(j.getRobots());
		}
		return resultado;
	}	

	public void addJugador(Jugador jugador){		
		this.jugadores.add(jugador);		
	}
	
	public List<Jugador> getJugadores(){
		return this.jugadores;
	}

	public List<Robot> getRobotsSistema() {
		return robotsSistema;
	}

	public void setRobotsSistema(List<Robot> robotsSistema) {
		this.robotsSistema = robotsSistema;
	}

	public List<MejoraDeRobot> getMejorasDisponibles() {
		return mejorasDisponibles;
	}

	public void setMejorasDisponibles(List<MejoraDeRobot> mejorasDisponibles) {
		this.mejorasDisponibles = mejorasDisponibles;
	}
	
	public void agregarRobot(Robot robot){
		this.robotsSistema.add(robot);
	}

	public void comprarRobot(int oferta, Robot robotSeleccionado, Jugador jugador) {
		if(!this.elRobotMePertenece(robotSeleccionado)){
			jugador.incrementarDinero(oferta);
			robotSeleccionado.setDuenio(null);
			this.robotsSistema.add(robotSeleccionado);
			jugador.getRobots().remove(robotSeleccionado);
		}			
	}
	
	public boolean elRobotMePertenece(Robot robotSeleccionado) {		
		return this.getRobotsSistema().contains(robotSeleccionado);
	}

	public int ofertarPorUnRobot(int precioRobot){
	
		double indice = (1 - ((new Random().nextInt(9)) + 2) /100);
		return (int) (precioRobot * indice);
	}

	public int getCostoDeReparacion(int danioAReparar) {
		return danioAReparar * 25;
	}
	
	public Robot buscarRobotPropio(long id){
		Robot robot = null;
		for(Robot current : this.getRobotsSistema()){
			if(current.getId() == id)
				robot = current;
		}
		return robot;
	}

	public void jugadorRechazaOferta(Robot robotAVender) {
		
		robotAVender.setDanio(robotAVender.getDanio() + 1);
	}
	
}
